/*!
    \file    dmx512.h
    \brief   DMX512灯带驱动头文件

    \version 2025-01-20, V1.0.0, DMX512驱动 for GD32C231C
*/

#ifndef DMX512_H
#define DMX512_H

#include "gd32c2x1.h"
#include <stdint.h>
#include <stdbool.h>

/* DMX512协议常量定义 */
#define DMX512_BREAK_TIME_US        88      /* Break信号最小时间 88us */
#define DMX512_MAB_TIME_US          8       /* Mark After Break最小时间 8us */
#define DMX512_SLOT_TIME_US         44      /* 每个数据槽最小时间 44us */
#define DMX512_MAX_CHANNELS         512     /* DMX512最大通道数 */
#define DMX512_START_CODE           0x00    /* DMX512起始码 */

/* DMX512数据帧结构 */
#define DMX512_FRAME_SIZE           (DMX512_MAX_CHANNELS + 1)  /* 包含起始码 */

/* DMX512使用的UART配置 */
#define DMX512_UART                 USART1          /* 使用USART1 */
#define DMX512_UART_BAUDRATE        250000          /* DMX512标准波特率 250kbps */
#define DMX512_UART_IRQ             USART1_IRQn     /* USART1中断 */

/* DMX512使用的DMA配置 */
#define DMX512_DMA_CHANNEL          DMA_CH1         /* 使用DMA通道1 */
#define DMX512_DMA_REQUEST          DMA_REQUEST_USART1_TX  /* USART1发送DMA请求 */
#define DMX512_DMA_IRQ              DMA_Channel1_IRQn      /* DMA通道1中断 */

/* DMX512 GPIO配置 */
#define DMX512_TX_PORT              GPIOA           /* 发送引脚端口 */
#define DMX512_TX_PIN               GPIO_PIN_2      /* 发送引脚 PA2 */
#define DMX512_TX_AF                GPIO_AF_1       /* 复用功能 */

/* DMX512数据使能(DE)引脚配置（可选）
   如果硬件接了收发器DE/RE脚，请在项目编译选项中定义DMX512_USE_DE，
   否则默认不使用DE控制，仅使用PA2发送 */
/* 可选：如果你的硬件带有DE(方向控制)引脚，请取消下一行注释并连接PA1 */
#define DMX512_USE_DE 

/* DE引脚定义（当使用时） */
#define DMX512_DE_PORT      GPIOA
#define DMX512_DE_PIN       GPIO_PIN_1

/* 根据是否使用DE引脚选择宏行为 */
#ifdef DMX512_USE_DE
    #define DMX512_DE_ENABLE()   gpio_bit_set(DMX512_DE_PORT, DMX512_DE_PIN)
    #define DMX512_DE_DISABLE()  gpio_bit_reset(DMX512_DE_PORT, DMX512_DE_PIN)
#else
    /* 未使用DE引脚时为空操作，确保代码可编译运行 */
    #define DMX512_DE_ENABLE()   ((void)0)
    #define DMX512_DE_DISABLE()  ((void)0)
#endif

/* DMX512状态枚举 */
typedef enum {
    DMX512_STATE_IDLE = 0,      /* 空闲状态 */
    DMX512_STATE_BREAK,         /* 发送Break信号 */
    DMX512_STATE_MAB,           /* 发送Mark After Break */
    DMX512_STATE_DATA,          /* 发送数据 */
    DMX512_STATE_COMPLETE       /* 发送完成 */
} dmx512_state_t;

/* RGB颜色结构体 */
typedef struct {
    uint8_t red;                /* 红色分量 0-255 */
    uint8_t green;              /* 绿色分量 0-255 */
    uint8_t blue;               /* 蓝色分量 0-255 */
} rgb_color_t;

/* DMX512控制结构体 */
typedef struct {
    uint8_t data[DMX512_FRAME_SIZE];    /* DMX512数据缓冲区 */
    uint16_t channel_count;             /* 使用的通道数量 */
    uint16_t current_channel;           /* 当前发送的通道 */
    dmx512_state_t state;               /* 当前状态 */
    bool transmission_complete;         /* 传输完成标志 */
    bool auto_refresh;                  /* 自动刷新标志 */
    uint32_t refresh_interval_ms;       /* 刷新间隔(毫秒) */
} dmx512_handle_t;

/* 全局DMX512句柄 */
extern dmx512_handle_t g_dmx512;

/* DMX512驱动函数声明 */

/*!
    \brief      初始化DMX512驱动
    \param[in]  channel_count: 使用的DMX512通道数量 (1-512)
    \param[out] none
    \retval     none
*/
void dmx512_init(uint16_t channel_count);

/*!
    \brief      反初始化DMX512驱动
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_deinit(void);

/*!
    \brief      设置DMX512通道数据
    \param[in]  channel: 通道号 (1-512)
    \param[in]  value: 通道值 (0-255)
    \param[out] none
    \retval     none
*/
void dmx512_set_channel(uint16_t channel, uint8_t value);

/*!
    \brief      获取DMX512通道数据
    \param[in]  channel: 通道号 (1-512)
    \param[out] none
    \retval     通道值 (0-255)
*/
uint8_t dmx512_get_channel(uint16_t channel);

/*!
    \brief      设置RGB灯带颜色
    \param[in]  start_channel: 起始通道号 (1-510)
    \param[in]  color: RGB颜色值
    \param[out] none
    \retval     none
*/
void dmx512_set_rgb(uint16_t start_channel, rgb_color_t color);

/*!
    \brief      设置多个RGB灯带颜色
    \param[in]  start_channel: 起始通道号 (1-510)
    \param[in]  colors: RGB颜色数组
    \param[in]  count: 灯珠数量
    \param[out] none
    \retval     none
*/
void dmx512_set_rgb_array(uint16_t start_channel, rgb_color_t *colors, uint16_t count);

/*!
    \brief      发送DMX512数据帧
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_send_frame(void);

/*!
    \brief      检查DMX512传输是否完成
    \param[in]  none
    \param[out] none
    \retval     true: 传输完成, false: 传输中
*/
bool dmx512_is_transmission_complete(void);

/*!
    \brief      启用DMX512自动刷新
    \param[in]  interval_ms: 刷新间隔(毫秒)
    \param[out] none
    \retval     none
*/
void dmx512_enable_auto_refresh(uint32_t interval_ms);

/*!
    \brief      禁用DMX512自动刷新
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_disable_auto_refresh(void);

/*!
    \brief      DMX512定时器中断处理函数
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_timer_irq_handler(void);

/*!
    \brief      DMX512 UART中断处理函数
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_uart_irq_handler(void);

/*!
    \brief      DMX512 DMA中断处理函数
    \param[in]  none
    \param[out] none
    \retval     none
*/
void dmx512_dma_irq_handler(void);

/* DMX512灯带效果函数 */

/*!
    \brief      设置所有灯带为单一颜色
    \param[in]  color: RGB颜色值
    \param[in]  led_count: 灯珠数量
    \param[out] none
    \retval     none
*/
void dmx512_set_all_color(rgb_color_t color, uint16_t led_count);

/*!
    \brief      彩虹效果
    \param[in]  led_count: 灯珠数量
    \param[in]  offset: 颜色偏移量
    \param[out] none
    \retval     none
*/
void dmx512_rainbow_effect(uint16_t led_count, uint8_t offset);

/*!
    \brief      呼吸灯效果
    \param[in]  color: 基础颜色
    \param[in]  led_count: 灯珠数量
    \param[in]  brightness: 亮度 (0-255)
    \param[out] none
    \retval     none
*/
void dmx512_breathing_effect(rgb_color_t color, uint16_t led_count, uint8_t brightness);

/*!
    \brief      流水灯效果
    \param[in]  color: 流水灯颜色
    \param[in]  led_count: 灯珠数量
    \param[in]  position: 当前位置
    \param[in]  tail_length: 拖尾长度
    \param[out] none
    \retval     none
*/
void dmx512_flowing_effect(rgb_color_t color, uint16_t led_count, uint16_t position, uint8_t tail_length);

/* 颜色工具函数 */

/*!
    \brief      HSV转RGB颜色
    \param[in]  hue: 色调 (0-359)
    \param[in]  saturation: 饱和度 (0-255)
    \param[in]  value: 明度 (0-255)
    \param[out] none
    \retval     RGB颜色值
*/
rgb_color_t dmx512_hsv_to_rgb(uint16_t hue, uint8_t saturation, uint8_t value);

/*!
    \brief      调整RGB颜色亮度
    \param[in]  color: 原始颜色
    \param[in]  brightness: 亮度系数 (0-255)
    \param[out] none
    \retval     调整后的RGB颜色值
*/
rgb_color_t dmx512_adjust_brightness(rgb_color_t color, uint8_t brightness);

/* 预定义颜色常量 */
#define DMX512_COLOR_BLACK      ((rgb_color_t){0, 0, 0})
#define DMX512_COLOR_WHITE      ((rgb_color_t){255, 255, 255})
#define DMX512_COLOR_RED        ((rgb_color_t){255, 0, 0})
#define DMX512_COLOR_GREEN      ((rgb_color_t){0, 255, 0})
#define DMX512_COLOR_BLUE       ((rgb_color_t){0, 0, 255})
#define DMX512_COLOR_YELLOW     ((rgb_color_t){255, 255, 0})
#define DMX512_COLOR_CYAN       ((rgb_color_t){0, 255, 255})
#define DMX512_COLOR_MAGENTA    ((rgb_color_t){255, 0, 255})
#define DMX512_COLOR_ORANGE     ((rgb_color_t){255, 165, 0})
#define DMX512_COLOR_PURPLE     ((rgb_color_t){128, 0, 128})

#endif /* DMX512_H */